﻿#include "BubbleSort.hpp"
#include "InsertSort.hpp"
#include "MergeSort.hpp"
#include "printSpan.hpp"
#include "QuickSort.hpp"
#include "SelectSort.hpp"
#include "ShellSort.hpp"
#include <algorithm>
#include <concepts>
#include <iostream>
#include <random>
#include <type_traits>
#include <vector>
#include "HeapSort.hpp"
#include <functional>

using namespace std;

void insertSortTest() {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	insertSort(std::span{ test_array });

	printSpan("before:", std::span{ test_array });
}

void selectSortTest() {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	selectSort(std::span{ test_array });

	printSpan("before:", std::span{ test_array });
}

void bubbleSortTest() {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	bubbleSort(std::span{ test_array });

	printSpan("before:", std::span{ test_array });
}

void shellSortTest() {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	shellSort(std::span{ test_array });

	printSpan("before:", std::span{ test_array });
}

void mergeSortTest() {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	mergeSort(std::span{ test_array });

	printSpan("before:", std::span{ test_array });
}

template <typename Func>
void sortTest(Func sortFun) {
	std::vector<int> test_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
	auto rng = std::default_random_engine{};
	std::shuffle(std::begin(test_array), std::end(test_array), rng);

	printSpan("before:", std::span{ test_array });

	sortFun(test_array.begin(), test_array.end());

	printSpan("after:", std::span{ test_array });
}


int main()
{
	cout << "--------------BubbleSort--------------" << endl;
	bubbleSortTest();
	cout << "--------------SelectSort--------------" << endl;
	selectSortTest();
	cout << "--------------InsertSort--------------" << endl;
	insertSortTest();
	cout << "--------------shellSort--------------" << endl;
	shellSortTest();
	cout << "--------------mergeSort--------------" << endl;
	mergeSortTest();
	cout << "--------------quickSort--------------" << endl;
	sortTest([](auto first, auto last) {
		return quickSort(first, last);
	});
	cout << "--------------heapSort--------------" << endl;
	sortTest([](auto first, auto last) {
		return heapSort(first, last);
	});
}

